/**
 * 
 */
package game.kill.biz.impl;

import game.kill.biz.RoomBiz;
import game.kill.biz.StepEngineBiz;
import game.kill.enums.GameStepEnum;
import game.kill.enums.PlayerRoleEnum;
import game.kill.enums.PlayerStatusEnum;
import game.kill.enums.RoomActionEnum;
import game.kill.enums.RoomStatusEnum;
import game.kill.exception.KillException;
import game.kill.exception.KillException.KillErrorCode;
import game.kill.model.GameRoomInfo;
import game.kill.model.Room;
import game.kill.model.RoomUser;
import game.kill.model.User;
import game.kill.service.RoomService;
import game.kill.service.RoomUserService;
import game.kill.service.UserService;

import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * @author leiruiqi
 *
 */
@Service("roomBiz")
public class RoomBizImpl implements RoomBiz {

	@Resource
	private RoomService roomService;
	
	@Resource
	private RoomUserService roomUserService;
	
	@Resource
	private UserService userService;
	
	@Resource
	private StepEngineBiz stepEngineBiz;
	
	@PostConstruct
	public void init(){
		findAliveRoomIntoStepEngine();
	}
	
	private void findAliveRoomIntoStepEngine(){
		List<Room> list = roomService.findAllRoomByStatus(RoomStatusEnum.ongoing.getCode());
		for(Room room:list){
			GameRoomInfo gameRoomInfo = getUserRoomInfo(room.getId());
			if(gameRoomInfo!=null){
				GameStepEnum stepEnum = GameStepEnum.getByName(gameRoomInfo.getRoom().getStep());
				stepEngineBiz.addGameSchedule(gameRoomInfo, stepEnum.getTime());
			}
			
		}
	}
	@Override
	public GameRoomInfo getUserRoomInfo(Long roomId) {
		Room room = roomService.getById(roomId);
		if(room == null){
			throw new KillException(KillErrorCode.PARAM_ERROR,"房间号不存在");
		}
		List<RoomUser> roomUserList = roomUserService.queryRoomUserByRoomId(roomId);
		Set<Long> userIdSet = Sets.newConcurrentHashSet();
		Map<Integer,RoomUser> roleMap = Maps.newHashMap();
		for(RoomUser roomUser:roomUserList){
			if(roomUser.getUserId()!=null){
				userIdSet.add(roomUser.getUserId());
			}
			roleMap.put(roomUser.getNumber(), roomUser);
		}
		
		Map<Long,User> userMap = userService.getUserMapByIds(userIdSet);
		for(RoomUser roomUser:roomUserList){
			if(roomUser.getUserId()!=null){
				User user = userMap.get(roomUser.getUserId());
				roomUser.setName(user.getName());
			}
		}
		GameRoomInfo gameRoomInfo = new GameRoomInfo();
		gameRoomInfo.setRoom(room);
		gameRoomInfo.setRoomUserMap(roleMap);
		return gameRoomInfo;
	}

	@Override
	public RoomUser getEffectRoomUserByUserId(Long userId) {
		RoomUser roomUser = roomUserService.getLastRoomUserByUserIdAndStatus(userId,1);
		if(roomUser == null){
			return null;
		}
		if(roomUser.getStatus() != 1){
			//throw new KillException(KillErrorCode.STATUE_ERROR,"房间号不存在");
			return null;
		}
		return roomUser;
	}

	@Override
	public void doRoomAction(Long userId, Long roomId,RoomActionEnum roomAction) {
		// 进入房间
		if(roomAction == RoomActionEnum.in){
			
			GameRoomInfo gameRoomInfo = getUserRoomInfo(roomId);
			Room room = gameRoomInfo.getRoom();
			
			if(room != null && room.getStatus()!=RoomStatusEnum.waiting.getCode()){
				throw new KillException(KillErrorCode.PARAM_ERROR,"房间当前状态不能进入");
			}
			if(gameRoomInfo.getRoomUserMap().size() >= room.getPlayerNum()){
				throw new KillException(KillErrorCode.PARAM_ERROR,"房间人数已满");
			}
			RoomUser roomUser = getAndCreateRandomRoomUser(gameRoomInfo,userId);
			gameRoomInfo.getRoomUserMap().put(roomUser.getNumber(), roomUser);
			if(gameRoomInfo.isNeedStart()){
				room.setStatus(RoomStatusEnum.ongoing.getCode());
				roomService.updateStatus(room);
				stepEngineBiz.addGameSchedule(gameRoomInfo,GameStepEnum.dark_work.getTime());
			}
			
		}
		else if(roomAction == RoomActionEnum.out){
			GameRoomInfo gameRoomInfo = getUserRoomInfo(roomId);
			Room room = gameRoomInfo.getRoom();
			
			if(room != null && room.getStatus() == RoomStatusEnum.waiting.getCode()){
				RoomUser roomUser = gameRoomInfo.findByUserId(userId);
				if(roomUser!=null){
					roomUserService.removePlayerById(roomUser.getId());
				}
			}else if(room.getStatus() != RoomStatusEnum.ongoing.getCode()){
				RoomUser roomUser = gameRoomInfo.findByUserId(userId);
				
				if(roomUser!=null && roomUser.getStatus() != PlayerStatusEnum.leave.getCode()){
					roomUser.setStatus(PlayerStatusEnum.leave.getCode());
					roomUserService.updatePlayerById(roomUser);
				}
			}else{
				//啥都不做
			}
		}
		
	}
	
	private RoomUser getAndCreateRandomRoomUser(GameRoomInfo gameRoomInfo,Long userId){
		Integer allNum = gameRoomInfo.getRoom().getPlayerNum();
		Set<Integer> aliveNumSet = gameRoomInfo.getRoomUserMap().keySet();
		List<Integer> tempAllNumSet = Lists.newArrayList();
		for(int i=1;i<=allNum;i++){
			tempAllNumSet.add(i);
		}
		tempAllNumSet.removeAll(aliveNumSet);
		int tempSize = tempAllNumSet.size();
		int randomNum = new Random().nextInt(tempSize);
		int playerNum = tempAllNumSet.get(randomNum);
		PlayerRoleEnum role = getRoleByPlayerNum(playerNum,allNum);
		
		RoomUser roomUser = new RoomUser();
		roomUser.setRoomId(gameRoomInfo.getRoom().getId());
		roomUser.setNumber(playerNum);
		roomUser.setRoleId(role.getCode());
		roomUser.setUserId(userId);
		roomUser.setStatus(PlayerStatusEnum.normal.getCode());
		roomUserService.createPlayer(roomUser);
		return roomUser;
	}
	
	private PlayerRoleEnum getRoleByPlayerNum(int num,int allNum){
		if(allNum>=7 && allNum <=10){
			if(num<=2){
				return PlayerRoleEnum.killer;
			}
			else if(num<=4){
				return PlayerRoleEnum.police;
			}
			else {
				return PlayerRoleEnum.everyman;
			}
		}
		
		else if(allNum>=11 && allNum <=14){
			if(num<=3){
				return PlayerRoleEnum.killer;
			}
			else if(num<=6){
				return PlayerRoleEnum.police;
			}
			else {
				return PlayerRoleEnum.everyman;
			}
		}
		
		else if(allNum>=15 && allNum <=16){
			if(num<=4){
				return PlayerRoleEnum.killer;
			}
			else if(num<=8){
				return PlayerRoleEnum.police;
			}
			else {
				return PlayerRoleEnum.everyman;
			}
		}
		else{
			throw new KillException(KillErrorCode.PARAM_ERROR,"获取角色参数错误");
		}
	}

	@Override
	public Room createRoom(Long masterUserId,Integer playUserNum) {
		if(playUserNum<7){
			throw new KillException(KillErrorCode.PARAM_ERROR,"房间人数不能少于7人");
		}
		if(playUserNum>16){
			throw new KillException(KillErrorCode.PARAM_ERROR,"房间人数不能大于16人");
		}
		Room room  = new Room();
		room.setMasterId(masterUserId);
		room.setPlayerNum(playUserNum);
		
		room.setStatus(RoomStatusEnum.waiting.getCode());
		room.setStep(GameStepEnum.dark_work.name());
		room.setRound(1);
		roomService.save(room);
		return room;
	}

}
